package admin

import (
	"exercise/application/yiran/app/libs"
	"exercise/application/yiran/app/model"
	"exercise/application/yiran/app/request/adminRequest"
	"fmt"
	"github.com/gin-gonic/gin"
	"strings"
)

type scoreRuleService struct {
	ctx *gin.Context
}

// List 列表
func (rev *scoreRuleService) List(request *adminRequest.ScoreRuleListRequest) (map[string]interface{}, error) {
	schoolId, _ := rev.ctx.Get("schoolId")
	list := make([]model.StudentScoreRule, 0)
	paging := model.Paging{}
	paging.Page = request.Page
	paging.PageSize = request.PageSize

	total, err := model.NewDb("").FindAllAndCount(&list, "school_id = ? ", []interface{}{schoolId}, model.OrderOrGroup{}, paging, []string{})

	if err != nil {
		return nil, fmt.Errorf("暂无数据：%w", err)
	}

	return map[string]interface{}{
		"list":  list,
		"total": total,
	}, err
}

// Add 新增
func (rev *scoreRuleService) Add(request *adminRequest.AddScoreRuleRequest) (id int64, err error) {

	schoolId, _ := rev.ctx.Get("schoolId")
	rule := new(model.StudentScoreRule)

	rule.Year = request.Year
	rule.TypeID = request.TypeId
	rule.SchoolID = schoolId.(int64)
	rule.JsRule = request.JsRule
	rule.JsName = request.JsName
	rule.JsRange = request.JsRange
	rule.RankSort = request.RankSort
	rule.CreateTime = libs.CurrentTime()

	err = model.NewDb("").InsertRecord(rule)
	if err != nil {
		return id, err
	}

	return rule.Id, nil
}

// Edit 编辑
func (rev *scoreRuleService) Edit(request *adminRequest.EditScoreRuleRequest) error {
	rule := new(model.StudentScoreRule)
	err := model.NewDb("").FindOne(rule, "id = ? ", []interface{}{request.Id}, "*", []string{})
	if err != nil {
		return err
	}

	rule.TypeID = request.TypeId
	rule.JsRule = request.JsRule
	rule.JsName = request.JsName
	rule.JsRange = request.JsRange
	rule.RankSort = request.RankSort

	err = model.NewDb("").SaveRecord(rule)
	if err != nil {
		return err
	}
	return nil
}

// Detail 详情
func (rev *scoreRuleService) Detail() (res interface{}, err error) {
	id := rev.ctx.Param("id")
	rule := new(model.StudentScoreRule)

	detail := make(map[string]interface{}, 0)

	//query := model.NewDb("").Query()
	//err = query.Model(rule).Where("id = ?", id).Select("id,js_name,js_range,js_rule,rank_sort").First(&detail).Error

	err = model.NewDb("").FindOneMap(rule, "id = ?", []interface{}{id}, "id,js_name,js_range,js_rule,rank_sort", &detail)

	if err != nil {
		return nil, fmt.Errorf("数据异常：%w", err)
	}

	sql, where := rev.GetJsStudentRange(detail["js_range"].(string))
	fmt.Printf("sql = %v \n", sql)
	fmt.Printf("where = %v \n", where)

	sql = rev.GetScoreJsRule(detail["js_rule"].(string))
	fmt.Printf("sql23 = %v \n", sql)

	//处理人员范围
	if detail["js_range"] != nil {
		jsRange := make(map[string]interface{}, 0)
		libs.JsonDecode([]byte(detail["js_range"].(string)), &jsRange)
		detail["js_range"] = jsRange
	}

	//处理计算规则
	if detail["js_rule"] != nil {
		jsRule := make(map[string]interface{}, 0)
		libs.JsonDecode([]byte(detail["js_rule"].(string)), &jsRule)
		detail["js_rule"] = jsRule
	}
	return detail, err
}

// Deleted 删除
func (rev *scoreRuleService) Deleted() error {
	id := rev.ctx.Param("id")
	rule := new(model.StudentScoreRule)
	err := model.NewDb("").DeleteRecord(rule, "id = ?", []interface{}{id})
	return err
}

// GetJsStudentRange 获取计算的学生范围
func (rev *scoreRuleService) GetJsStudentRange(jsRange string) (sql string, where []interface{}) {
	where = make([]interface{}, 0)
	if jsRange != "" {
		stuRange := make(map[string]interface{}, 0)
		libs.JsonDecode([]byte(jsRange), &stuRange)
		for k, v := range stuRange {
			if libs.IsSlice(v) { //参数是切片
				vv := v.([]interface{})[0]
				op := strings.ToUpper(v.([]interface{})[1].(string))

				sql += k + " " + op + " ? AND "
				//判断是否存在in查询
				if strings.Contains(op, "IN") {
					where = append(where, strings.Split(vv.(string), ","))
				}
				//判断是否存在like
				if strings.Contains(op, "LIKE") {
					where = append(where, "%"+vv.(string)+"%")
				}
				continue
			}

			sql += k + " = ? AND "
			where = append(where, v)
		}
	}

	return strings.TrimRight(sql, " AND "), where
}

// GetScoreJsRule 分数计算规则
func (rev *scoreRuleService) GetScoreJsRule(rule string) (sql string) {
	if rule != "" {
		jsRule := make(map[string]interface{}, 0)
		libs.JsonDecode([]byte(rule), &jsRule)

		for k, r := range jsRule {
			s := ""
			for kk, vv := range r.(map[string]interface{}) {
				s += "`" + kk + "` * " + libs.Float64String(vv.(float64), 2) + " + "
			}
			sql += "`" + k + "` = " + "(" + strings.TrimRight(s, " + ") + "),"
		}
	}
	return strings.TrimRight(sql, ",")
}

// GetRankSort 获取排序规则
func (rev *scoreRuleService) GetRankSort(rankSort string) string {
	orderBy := ""
	rank := strings.Split(rankSort, ",")
	for _, s := range rank {
		orderBy += s + " DESC,"
	}
	return strings.TrimRight(orderBy, ",")
}

func NewScoreRuleService(c *gin.Context) *scoreRuleService {
	return &scoreRuleService{
		ctx: c,
	}
}
